# -*- coding: utf-8 -*-

from staffmanager import datamodels
from staffmanager.common import constant
from staffmanager.common import exception
from staffmanager.common import help
from staffmanager.prettytable import PrintStaffBase


SORT = 'sort'
NAME = 'name'
DATE = 'entry_date'
DEPARTMENT = 'department'
POSITION = 'position'
ID = 'id'
ACT = 'act'
# 员工信息
STAFFS = {}


class Staff(object):
    """员工实例类"""
    def __init__(self, staffs):
        self.name = staffs[NAME]
        self.id = staffs[ID]
        self.entry_date = staffs[DATE]
        self.department = staffs[DEPARTMENT]
        self.position = staffs[POSITION]

    def __getitem__(self, item):
        return self.__dict__[item]


class OpActionBase(object):
    """员工操作类"""
    def __init__(self, oper_obj):
        self.oper_obj = oper_obj
        self.infos = []
        self.tb = PrintStaffBase()

    def action(self):
        pass

    @staticmethod
    def exit(data):
        exit(0)

    @staticmethod
    def help(data):
        """返回帮助信息"""
        act = data.get(ACT, None)
        if not act:
            print(help.HELP_INFO)
            return help.HELP_INFO
        try:
            print(help.HELP_ACT[act])
            return help.HELP_ACT[act]
        except KeyError:
            raise exception.HelpKeyErrorEXception

    @datamodels.json_validate(schema=datamodels.schema_add)
    def add(self, data):
        e_id = data['id']

        if e_id in STAFFS:
            raise exception.StaffRepeatEXception
        staff = Staff(data)
        STAFFS[e_id] = staff
        print(constant.ADD_SUCCESS)

    @datamodels.json_validate(schema=datamodels.schema_del_get)
    def delete(self, data):
        e_id = data['id']

        try:
            del STAFFS[e_id]
            print(constant.DELETE_SUCCESS)
            return e_id
        except KeyError:
            raise exception.StaffNotFoundException

    @datamodels.json_validate(schema=datamodels.schema_update)
    def update(self, data):
        e_id = data.pop(ID, None)
        if e_id not in STAFFS:
            raise exception.StaffNotFoundException

        for k, v in STAFFS.items():
            if v.id == e_id:
                for _k, _v in data.items():
                    setattr(v, _k, _v)

                print(constant.UPDATE_SUCCESS)
                return v

    @datamodels.json_validate(schema=datamodels.schema_del_get)
    def get(self, data):
        e_id = data['id']
        if e_id not in STAFFS:
            raise exception.StaffNotFoundException
        staff_tb = self.tb.print_staff(STAFFS[e_id])
        print(staff_tb)
        return STAFFS[e_id]

    @datamodels.json_validate(schema=datamodels.schema_list)
    def list(self, data):
        if not data:
            staffs = list(STAFFS.values())
            staff_tb = self.tb.print_staff(staffs)
            print(staff_tb)
            return staffs

        tmp_staffs = self.filter_staffs(data)

        staff_tb = self.tb.print_staff(tmp_staffs)
        print(staff_tb)
        return tmp_staffs

    def filter_staffs(self, data):
        sort = data.pop(SORT, None)
        staffs = list(STAFFS.values())
        tmp_staffs = list()

        for param_key in data.keys():
            for staff in staffs:
                if getattr(staff, param_key) == data[param_key]:
                    tmp_staffs.append(staff)
            staffs = tmp_staffs
            tmp_staffs = list()

        staffs = self.staff_sort(staffs, sort)
        return staffs

    @staticmethod
    def staff_sort(staffs, sort):
        if not sort:
            return staffs

        sort_info = sort.split(":")
        sort_filed = sort_info[0]
        direct = sort_info[1]
        is_desc = False if direct == 'ASC' else True
        # 根据字段排序
        staffs.sort(key=lambda x: x[sort_filed], reverse=is_desc)

        return staffs


class OpAction(OpActionBase):

    def action(self):
        act = self.oper_obj.action
        try:
            # 解析出需要执行的命令
            action = getattr(self, act)
        except AttributeError:
            raise exception.ActEXception
        data = {}

        for field in [NAME, ID, DATE, DEPARTMENT, POSITION, SORT, ACT]:
            field_value = getattr(self.oper_obj, field)
            if field_value is not None:
                data[field] = field_value
        try:
            return action(data)
        except Exception as e:
            print(e.msg)
            return e.msg
